package com.lex.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lex.common.api.CommonResult;
import com.lex.data.admin.mapper.LexCmsRoleMapper;
import com.lex.data.admin.mapper.LexCmsUserRoleMapper;
import com.lex.data.admin.model.LexCmsRole;
import com.lex.data.admin.model.LexCmsRoleMenu;
import com.lex.data.admin.model.LexCmsUserRole;
import com.lex.data.admin.service.LexCmsRoleMenuService;
import com.lex.entity.params.RoleListQueryParams;
import com.lex.entity.params.UpdateRoleStateParams;
import com.lex.entity.role.RoleDto;
import com.lex.entity.role.RoleListDto;
import com.lex.entity.role.RoleListVo;
import com.lex.mapper.RoleListMapper;
import com.lex.service.RoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Service
public class RoleServiceImpl implements RoleService {

    @Autowired
    private RoleListMapper roleListMapper;

    @Autowired
    private LexCmsRoleMapper roleMapper;

    @Autowired
    private LexCmsRoleMenuService roleMenuService;

    @Autowired
    private LexCmsUserRoleMapper userRoleMapper;

    /**
     * 获取角色列表,并且获取角色拥有的菜单列表
     * @param queryParams
     * @param pageSize
     * @param page
     * @return
     */
    @Override
    public CommonResult getRolelist(RoleListQueryParams queryParams, Integer pageSize, Integer page) {
        Page<LexCmsRole> rolePage = new Page<>(page, pageSize);
        List<RoleListDto> roleList = roleListMapper.getRoleList(queryParams, rolePage);
        List<RoleListVo> roleListVos = roleList.stream().map(role -> {
            RoleListVo roleListVo = new RoleListVo();
            roleListVo.setId(role.getId());
            roleListVo.setRoleName(role.getRoleName());
            roleListVo.setOrderNo(0);
            roleListVo.setStatus(role.getStatus());
            roleListVo.setCreateTime(String.valueOf(role.getCreateTime()));
            roleListVo.setRemark(role.getRemark());
            ArrayList<Long> menuList = new ArrayList<>();
            role.getMenuIds().forEach(menuId -> {
                menuList.add(menuId.getMenuId());
            });
            roleListVo.setMenu(menuList);
            return roleListVo;
        }).toList();
        long total = rolePage.getTotal();
        HashMap<String, Object> result = new HashMap<>();
        result.put("total", total);
        result.put("items", roleListVos);
        return CommonResult.success(result);
    }

    /**
     * 添加角色，并且添加角色菜单关系
     * @param addRole
     * @return
     */
    @Override
    @Transactional
    public CommonResult addRole(RoleDto addRole) {
        LexCmsRole role = new LexCmsRole();
        role.setRoleName(addRole.getRoleName());
        role.setRemark(addRole.getRemark());
        role.setStatus(addRole.getStatus());
        //获取当前时间戳
        long currentTimeMillis = System.currentTimeMillis();
        //转换为timestamp
        Timestamp time = new Timestamp(currentTimeMillis);
        role.setCreateTime(time);
        //插入角色
        int insert = roleMapper.insert(role);
        //处理角色菜单关系，然后采用批量插入
        updateRoleMenus(addRole, role.getId(), role);
        return insert > 0
                ? CommonResult.success("添加角色成功！")
                : CommonResult.failed("角色添加失败！");
    }

    @Transactional
    public void updateRoleMenus(RoleDto addRole, Long id, LexCmsRole role) {
        List<Long> menuIds = addRole.getMenuIds();
        List<LexCmsRoleMenu> roleMenus = new ArrayList<>();
        //判断menuIds是否为空
        if (menuIds == null) {
            return;
        }
        menuIds.forEach(menuId -> {
            LexCmsRoleMenu roleMenu = new LexCmsRoleMenu();
            roleMenu.setRoleId(id);
            roleMenu.setMenuId(menuId);
            roleMenus.add(roleMenu);
        });
        roleMenuService.saveBatch(roleMenus);
    }

    /**
     * 修改角色信息，同时修改角色菜单关系
     * @param updateRole
     * @return
     */
    @Override
    @Transactional
    public CommonResult updateRole(RoleDto updateRole) {
        LexCmsRole role = new LexCmsRole();
        role.setId(updateRole.getId());
        role.setRoleName(updateRole.getRoleName());
        role.setRemark(updateRole.getRemark());
        role.setStatus(updateRole.getStatus());
        //获取当前时间戳
        long currentTimeMillis = System.currentTimeMillis();
        //转换为timestamp
        Timestamp time = new Timestamp(currentTimeMillis);
        role.setUpdateTime(time);
        int update = roleMapper.updateById(role);
        //删除角色菜单关系
        roleMenuService.remove(new QueryWrapper<LexCmsRoleMenu>().eq("role_id", updateRole.getId()));
        //处理角色菜单关系，然后采用批量插入
        updateRoleMenus(updateRole, updateRole.getId(), role);
        return update > 0
                ? CommonResult.success("修改角色成功！")
                : CommonResult.failed("角色修改失败！");
    }
    /**
     * 删除角色
     * @param roleId
     * @return
     */
    @Override
    @Transactional
    public CommonResult deleteRole(Long roleId) {
        //判断角色下是否拥有用户，如果有用户则不能删除
        List<LexCmsUserRole> userRoles = userRoleMapper.selectList(
                new QueryWrapper<LexCmsUserRole>().eq("role_id", roleId));
        if (!userRoles.isEmpty()) {
            return CommonResult.failed("该角色下存在用户，不能删除！");
        }
        //删除角色
        int delete = roleMapper.deleteById(roleId);
        //删除角色菜单关系
        roleMenuService.remove(new QueryWrapper<LexCmsRoleMenu>().eq("role_id", roleId));
        return delete > 0
                ? CommonResult.success("删除角色成功！")
                : CommonResult.failed("角色删除失败！");
    }

    /**
     * 获取所有角色列表,状态为正常的角色
     * @return
     */
    @Override
    public CommonResult getAllRoleList() {
        List<LexCmsRole> roles = roleMapper.selectList(new QueryWrapper<LexCmsRole>().eq("status", 1));
        return CommonResult.success(roles);
    }

    /**
     * 修改角色状态
     * @param UpdateRoleStateParams
     * @return
     */
    @Override
    public CommonResult updateRoleStatus(UpdateRoleStateParams updateRoleStateDto) {
        LexCmsRole role = new LexCmsRole();
        role.setId(updateRoleStateDto.getRoleId());
        role.setStatus(updateRoleStateDto.getStatus());
        int update = roleMapper.updateById(role);
        return update > 0
                ? CommonResult.success("修改角色状态成功！")
                : CommonResult.failed("修改角色状态失败！");
    }
}
